<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>绘制线框立方体</title>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background-color: #f0f0f0;
      }
      canvas {
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
      attribute vec3 aPosition; // 位置坐标，注意这是3维坐标,而不是2维坐标
      void main() {
        float radian = radians(10.0); // 旋转角度
        float sinb = sin(radian);
        float cosb = cos(radian);
        // 绕x轴旋转的4维旋转矩阵
        mat4 rotatex = mat4(
          1.0, 0.0, 0.0, 0.0,
          0.0, cosb, -sinb, 0.0,
          0.0, sinb, cosb, 0.0,
          0.0, 0.0, 0.0, 1.0 // 4维齐次坐标
        );
        // 绕y轴旋转的4维旋转矩阵
        mat4 rotatey = mat4(
          cosb, 0.0, -sinb, 0.0,
          0.0, 1.0, 0.0, 0.0,
          sinb, 0.0, cosb, 0.0,
          0.0, 0.0, 0.0, 1.0 // 4维齐次坐标
        );

        gl_Position = rotatex * rotatey * vec4(aPosition, 1.0);  // 正确应用旋转矩阵
        gl_PointSize = 10.0; // 设置点的大小
      }
    </script>

    <!-- 片元着色器 -->
    <script id="fragment-shader" type="x-shader/x-fragment">
      precision mediump float; // 设置精度
      uniform vec4 uColor; // 颜色变量

      void main() {
        gl_FragColor = uColor; // 设置颜色
      }
    </script>
    <script type="module">
      import initShaders from "../utils/initShader.js";

      const canvas = document.getElementById("canvas");
      const gl = canvas.getContext("webgl");
      if (!gl) {
        console.error("WebGL not supported");
      }

      const program = initShaders(gl);
      /*
        [
          // 前面的坐标
          -0.5, -0.5, 0.5, // 左下前
          0.5, -0.5, 0.5, // 右下前
          0.5, 0.5, 0.5, // 右上前
          -0.5, 0.5, 0.5, // 左上前

          // 后面的坐标
          -0.5, -0.5, -0.5, // 左下后
          0.5, -0.5, -0.5, // 右下后
           0.5, 0.5, -0.5, // 右上后
          -0.5, 0.5, -0.5, // 左上后

          // 上面的坐标
          -0.5, 0.5, -0.5, // 左上后
          0.5, 0.5, -0.5, // 右上后
          0.5, 0.5, 0.5, // 右上前
          -0.5, 0.5, 0.5, // 左上前

          // 下面的坐标
          -0.5, -0.5, -0.5, // 左下后
          0.5, -0.5, -0.5, // 右下后
          0.5, -0.5, 0.5, // 右下前
          -0.5, -0.5, 0.5, // 左下前
          // 右面的坐标
          0.5, -0.5, -0.5, // 右下后
          0.5, -0.5, 0.5, // 右下前
          0.5, 0.5, 0.5, // 右上前
          0.5, 0.5, -0.5, // 右上后
          // 左面的坐标
          -0.5, -0.5, -0.5, // 左下后
          -0.5, -0.5, 0.5, // 左下前
          -0.5, 0.5, 0.5, // 左上前
          -0.5, 0.5, -0.5, // 左上后
        ]
      */
      // 位置坐标
      const vertices = new Float32Array(
        [
          [-0.5, -0.5, 0.5], // 0 左下前
          [0.5, -0.5, 0.5], // 1 右下前
          [0.5, 0.5, 0.5], // 2 右上前
          [-0.5, 0.5, 0.5], // 3 左上前

          [-0.5, -0.5, -0.5], // 4 左下后
          [0.5, -0.5, -0.5], // 5 右下后
          [0.5, 0.5, -0.5], // 6 右上后
          [-0.5, 0.5, -0.5], // 7 左上后
        ].flat()
      ); // 将二维数组展平为一维数组
      const buffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
      // 定义三角形的顶点的索引
      const indices = new Uint16Array(
        [
          // 前面(红色)，逆时针
          [0, 1, 2],
          [0, 2, 3],
          // 后面(绿色)，顺时针
          [4, 6, 5],
          [4, 7, 6],
          // 上面(蓝色)
          [3, 2, 6],
          [3, 6, 7],
          // 下面(黄色)
          [0, 5, 1],
          [0, 4, 5],
          // 右面(品红色)
          [1, 5, 6],
          [1, 6, 2],
          // 左面(青色)
          [0, 3, 7],
          [0, 7, 4],
        ].flat() // 将二维数组展平为一维数组
      );

      const indexBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // 绑定索引缓冲区
      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); // 将索引数据传入缓冲区

      // 获取变量的索引
      const aPosition = gl.getAttribLocation(program, "aPosition");
      gl.vertexAttribPointer(
        aPosition,
        3, // 每个点有3个坐标
        gl.FLOAT,
        false,
        3 * Float32Array.BYTES_PER_ELEMENT,
        0
      );
      gl.enableVertexAttribArray(aPosition); // 启用位置坐标
      // // 使用顶点索引绘制线框立方体
      // gl.drawElements(
      //   gl.TRIANGLES, // 绘制三角形
      //   indices.length, // 索引的数量
      //   gl.UNSIGNED_SHORT, // 索引的类型
      //   0 // 偏移量
      // ); // 绘制线框立方体
      // gl.enable(gl.DEPTH_TEST);
      gl.depthFunc(gl.LESS);
      gl.frontFace(gl.CCW); // 设置逆时针为正面
      gl.disable(gl.CULL_FACE); // 禁用背面剔除
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

      // 定义6个面的颜色
      const faceColors = [
        [1.0, 0.0, 0.0, 1.0], // 前面：red
        [0.0, 1.0, 0.0, 1.0], // 后面：green
        [0.0, 0.0, 1.0, 1.0], // 上面：blue
        [1.0, 1.0, 0.0, 1.0], // 下面：yellow
        [1.0, 0.0, 1.0, 1.0], // 右面：magenta 品红
        [0.0, 1.0, 1.0, 1.0], // 左面：cyan 青色
      ];
      // 获取颜色变量的索引
      const uColor = gl.getUniformLocation(program, "uColor");
      // 给每个面设置颜色变量的值
      for (let i = 0; i < faceColors.length; i++) {
        gl.uniform4fv(uColor, faceColors[i]); // 设置颜色变量的值
        console.log(
          "Drawing red face at index offset:",
          i * 6 * Uint16Array.BYTES_PER_ELEMENT
        );
        gl.drawElements(
          gl.TRIANGLES, // 绘制三角形
          6,
          gl.UNSIGNED_SHORT,
          i * 6 * Uint16Array.BYTES_PER_ELEMENT // 每6个索引绘制一个面
        );
      } // 绘制线框立方体的每个面
    </script>
  </body>
</html>
